Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

tinyxml.h

Go to the documentation of this file.
00001 /*
00002 www.sourceforge.net/projects/tinyxml
00003 Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
00004 
00005 This software is provided 'as-is', without any express or implied
00006 warranty. In no event will the authors be held liable for any
00007 damages arising from the use of this software.
00008 
00009 Permission is granted to anyone to use this software for any
00010 purpose, including commercial applications, and to alter it and
00011 redistribute it freely, subject to the following restrictions:
00012 
00013 1. The origin of this software must not be misrepresented; you must
00014 not claim that you wrote the original software. If you use this
00015 software in a product, an acknowledgment in the product documentation
00016 would be appreciated but is not required.
00017 
00018 2. Altered source versions must be plainly marked as such, and
00019 must not be misrepresented as being the original software.
00020 
00021 3. This notice may not be removed or altered from any source
00022 distribution.
00023 */
00024 
00025 
00026 #ifndef TINYXML_INCLUDED
00027 #define TINYXML_INCLUDED
00028 
00029 #ifdef _MSC_VER
00030 #pragma warning( disable : 4530 )
00031 #pragma warning( disable : 4786 )
00032 #endif
00033 
00034 #include <ctype.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <assert.h>
00039 
00040 // Help out windows:
00041 #if defined( _DEBUG ) && !defined( DEBUG )
00042 #define DEBUG
00043 #endif
00044 
00045 #if defined( DEBUG ) && defined( _MSC_VER )
00046 #include <windows.h>
00047 #define TIXML_LOG OutputDebugString
00048 #else
00049 #define TIXML_LOG printf
00050 #endif
00051 
00052 #ifdef TIXML_USE_STL
00053     #include <string>
00054     #include <iostream>
00055     //#include <ostream>
00056     #define TIXML_STRING    std::string
00057     #define TIXML_ISTREAM   std::istream
00058     #define TIXML_OSTREAM   std::ostream
00059 #else
00060     #include "tinystr.h"
00061     #define TIXML_STRING    TiXmlString
00062     #define TIXML_OSTREAM   TiXmlOutStream
00063 #endif
00064 
00065 class TiXmlDocument;
00066 class TiXmlElement;
00067 class TiXmlComment;
00068 class TiXmlUnknown;
00069 class TiXmlAttribute;
00070 class TiXmlText;
00071 class TiXmlDeclaration;
00072 
00073 class TiXmlParsingData;
00074 
00075 /*  Internal structure for tracking location of items 
00076     in the XML file.
00077 */
00078 struct TiXmlCursor
00079 {
00080     TiXmlCursor()       { Clear(); }
00081     void Clear()        { row = col = -1; }
00082 
00083     int row;    // 0 based.
00084     int col;    // 0 based.
00085 };
00086 
00087 
00088 // Only used by Attribute::Query functions
00089 enum 
00090 { 
00091     TIXML_SUCCESS,
00092     TIXML_NO_ATTRIBUTE,
00093     TIXML_WRONG_TYPE
00094 };
00095 
00096 /** TiXmlBase is a base class for every class in TinyXml.
00097     It does little except to establish that TinyXml classes
00098     can be printed and provide some utility functions.
00099 
00100     In XML, the document and elements can contain
00101     other elements and other types of nodes.
00102 
00103     @verbatim
00104     A Document can contain: Element (container or leaf)
00105                             Comment (leaf)
00106                             Unknown (leaf)
00107                             Declaration( leaf )
00108 
00109     An Element can contain: Element (container or leaf)
00110                             Text    (leaf)
00111                             Attributes (not on tree)
00112                             Comment (leaf)
00113                             Unknown (leaf)
00114 
00115     A Decleration contains: Attributes (not on tree)
00116     @endverbatim
00117 */
00118 class TiXmlBase
00119 {
00120     friend class TiXmlNode;
00121     friend class TiXmlElement;
00122     friend class TiXmlDocument;
00123 
00124 public:
00125     TiXmlBase()                             {}
00126     virtual ~TiXmlBase()                    {}
00127 
00128     /** All TinyXml classes can print themselves to a filestream.
00129         This is a formatted print, and will insert tabs and newlines.
00130         
00131         (For an unformatted stream, use the << operator.)
00132     */
00133     virtual void Print( FILE* cfile, int depth ) const = 0;
00134 
00135     /** The world does not agree on whether white space should be kept or
00136         not. In order to make everyone happy, these global, static functions
00137         are provided to set whether or not TinyXml will condense all white space
00138         into a single space or not. The default is to condense. Note changing this
00139         values is not thread safe.
00140     */
00141     static void SetCondenseWhiteSpace( bool condense )      { condenseWhiteSpace = condense; }
00142 
00143     /// Return the current white space setting.
00144     static bool IsWhiteSpaceCondensed()                     { return condenseWhiteSpace; }
00145 
00146     /** Return the position, in the original source file, of this node or attribute.
00147         The row and column are 1-based. (That is the first row and first column is
00148         1,1). If the returns values are 0 or less, then the parser does not have
00149         a row and column value.
00150 
00151         Generally, the row and column value will be set when the TiXmlDocument::Load(),
00152         TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
00153         when the DOM was created from operator>>.
00154 
00155         The values reflect the initial load. Once the DOM is modified programmatically
00156         (by adding or changing nodes and attributes) the new values will NOT update to
00157         reflect changes in the document.
00158 
00159         There is a minor performance cost to computing the row and column. Computation
00160         can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
00161 
00162         @sa TiXmlDocument::SetTabSize()
00163     */
00164     int Row() const         { return location.row + 1; }
00165     int Column() const      { return location.col + 1; }    ///< See Row()
00166 
00167 protected:
00168     // See STL_STRING_BUG
00169     // Utility class to overcome a bug.
00170     class StringToBuffer
00171     {
00172       public:
00173         StringToBuffer( const TIXML_STRING& str );
00174         ~StringToBuffer();
00175         char* buffer;
00176     };
00177 
00178     static const char*  SkipWhiteSpace( const char* );
00179     inline static bool  IsWhiteSpace( int c )       { return ( isspace( c ) || c == '\n' || c == '\r' ); }
00180 
00181     virtual void StreamOut (TIXML_OSTREAM *) const = 0;
00182 
00183     #ifdef TIXML_USE_STL
00184         static bool StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
00185         static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
00186     #endif
00187 
00188     /*  Reads an XML name into the string provided. Returns
00189         a pointer just past the last character of the name,
00190         or 0 if the function has an error.
00191     */
00192     static const char* ReadName( const char* p, TIXML_STRING* name );
00193 
00194     /*  Reads text. Returns a pointer past the given end tag.
00195         Wickedly complex options, but it keeps the (sensitive) code in one place.
00196     */
00197     static const char* ReadText(    const char* in,             // where to start
00198                                     TIXML_STRING* text,         // the string read
00199                                     bool ignoreWhiteSpace,      // whether to keep the white space
00200                                     const char* endTag,         // what ends this text
00201                                     bool ignoreCase );          // whether to ignore case in the end tag
00202 
00203     virtual const char* Parse( const char* p, TiXmlParsingData* data ) = 0;
00204 
00205     // If an entity has been found, transform it into a character.
00206     static const char* GetEntity( const char* in, char* value );
00207 
00208     // Get a character, while interpreting entities.
00209     inline static const char* GetChar( const char* p, char* _value )
00210     {
00211         assert( p );
00212         if ( *p == '&' )
00213         {
00214             return GetEntity( p, _value );
00215         }
00216         else
00217         {
00218             *_value = *p;
00219             return p+1;
00220         }
00221     }
00222 
00223     // Puts a string to a stream, expanding entities as it goes.
00224     // Note this should not contian the '<', '>', etc, or they will be transformed into entities!
00225     static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
00226 
00227     static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
00228 
00229     // Return true if the next characters in the stream are any of the endTag sequences.
00230     static bool StringEqual(    const char* p,
00231                                 const char* endTag,
00232                                 bool ignoreCase );
00233 
00234 
00235     enum
00236     {
00237         TIXML_NO_ERROR = 0,
00238         TIXML_ERROR,
00239         TIXML_ERROR_OPENING_FILE,
00240         TIXML_ERROR_OUT_OF_MEMORY,
00241         TIXML_ERROR_PARSING_ELEMENT,
00242         TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
00243         TIXML_ERROR_READING_ELEMENT_VALUE,
00244         TIXML_ERROR_READING_ATTRIBUTES,
00245         TIXML_ERROR_PARSING_EMPTY,
00246         TIXML_ERROR_READING_END_TAG,
00247         TIXML_ERROR_PARSING_UNKNOWN,
00248         TIXML_ERROR_PARSING_COMMENT,
00249         TIXML_ERROR_PARSING_DECLARATION,
00250         TIXML_ERROR_DOCUMENT_EMPTY,
00251 
00252         TIXML_ERROR_STRING_COUNT
00253     };
00254     static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
00255 
00256     TiXmlCursor location;
00257 
00258 private:
00259     struct Entity
00260     {
00261         const char*     str;
00262         unsigned int    strLength;
00263         char            chr;
00264     };
00265     enum
00266     {
00267         NUM_ENTITY = 5,
00268         MAX_ENTITY_LENGTH = 6
00269 
00270     };
00271     static Entity entity[ NUM_ENTITY ];
00272     static bool condenseWhiteSpace;
00273 };
00274 
00275 
00276 /** The parent class for everything in the Document Object Model.
00277     (Except for attributes).
00278     Nodes have siblings, a parent, and children. A node can be
00279     in a document, or stand on its own. The type of a TiXmlNode
00280     can be queried, and it can be cast to its more defined type.
00281 */
00282 class TiXmlNode : public TiXmlBase
00283 {
00284     friend class TiXmlDocument;
00285     friend class TiXmlElement;
00286 
00287 public:
00288     #ifdef TIXML_USE_STL    
00289 
00290         /** An input stream operator, for every class. Tolerant of newlines and
00291             formatting, but doesn't expect them.
00292         */
00293         friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
00294 
00295         /** An output stream operator, for every class. Note that this outputs
00296             without any newlines or formatting, as opposed to Print(), which
00297             includes tabs and new lines.
00298 
00299             The operator<< and operator>> are not completely symmetric. Writing
00300             a node to a stream is very well defined. You'll get a nice stream
00301             of output, without any extra whitespace or newlines.
00302             
00303             But reading is not as well defined. (As it always is.) If you create
00304             a TiXmlElement (for example) and read that from an input stream,
00305             the text needs to define an element or junk will result. This is
00306             true of all input streams, but it's worth keeping in mind.
00307 
00308             A TiXmlDocument will read nodes until it reads a root element, and
00309             all the children of that root element.
00310         */  
00311         friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
00312 
00313         /// Appends the XML node or attribute to a std::string.
00314         friend std::string& operator<< (std::string& out, const TiXmlNode& base );
00315 
00316     #else
00317         // Used internally, not part of the public API.
00318         friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
00319     #endif
00320 
00321     /** The types of XML nodes supported by TinyXml. (All the
00322             unsupported types are picked up by UNKNOWN.)
00323     */
00324     enum NodeType
00325     {
00326         DOCUMENT,
00327         ELEMENT,
00328         COMMENT,
00329         UNKNOWN,
00330         TEXT,
00331         DECLARATION,
00332         TYPECOUNT
00333     };
00334 
00335     virtual ~TiXmlNode();
00336 
00337     /** The meaning of 'value' changes for the specific type of
00338         TiXmlNode.
00339         @verbatim
00340         Document:   filename of the xml file
00341         Element:    name of the element
00342         Comment:    the comment text
00343         Unknown:    the tag contents
00344         Text:       the text string
00345         @endverbatim
00346 
00347         The subclasses will wrap this function.
00348     */
00349     const char * Value() const { return value.c_str (); }
00350 
00351     /** Changes the value of the node. Defined as:
00352         @verbatim
00353         Document:   filename of the xml file
00354         Element:    name of the element
00355         Comment:    the comment text
00356         Unknown:    the tag contents
00357         Text:       the text string
00358         @endverbatim
00359     */
00360     void SetValue(const char * _value) { value = _value;}
00361 
00362     #ifdef TIXML_USE_STL
00363     /// STL std::string form.
00364     void SetValue( const std::string& _value )    
00365     {     
00366         StringToBuffer buf( _value );
00367         SetValue( buf.buffer ? buf.buffer : "" );       
00368     }   
00369     #endif
00370 
00371     /// Delete all the children of this node. Does not affect 'this'.
00372     void Clear();
00373 
00374     /// One step up the DOM.
00375     TiXmlNode* Parent() const                   { return parent; }
00376 
00377     TiXmlNode* FirstChild() const   { return firstChild; }      ///< The first child of this node. Will be null if there are no children.
00378     TiXmlNode* FirstChild( const char * value ) const;          ///< The first child of this node with the matching 'value'. Will be null if none found.
00379 
00380     TiXmlNode* LastChild() const    { return lastChild; }       /// The last child of this node. Will be null if there are no children.
00381     TiXmlNode* LastChild( const char * value ) const;           /// The last child of this node matching 'value'. Will be null if there are no children.
00382 
00383     #ifdef TIXML_USE_STL
00384     TiXmlNode* FirstChild( const std::string& _value ) const    {   return FirstChild (_value.c_str ());    }   ///< STL std::string form.
00385     TiXmlNode* LastChild( const std::string& _value ) const     {   return LastChild (_value.c_str ()); }   ///< STL std::string form.
00386     #endif
00387 
00388     /** An alternate way to walk the children of a node.
00389         One way to iterate over nodes is:
00390         @verbatim
00391             for( child = parent->FirstChild(); child; child = child->NextSibling() )
00392         @endverbatim
00393 
00394         IterateChildren does the same thing with the syntax:
00395         @verbatim
00396             child = 0;
00397             while( child = parent->IterateChildren( child ) )
00398         @endverbatim
00399 
00400         IterateChildren takes the previous child as input and finds
00401         the next one. If the previous child is null, it returns the
00402         first. IterateChildren will return null when done.
00403     */
00404     TiXmlNode* IterateChildren( TiXmlNode* previous ) const;
00405 
00406     /// This flavor of IterateChildren searches for children with a particular 'value'
00407     TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous ) const;
00408 
00409     #ifdef TIXML_USE_STL
00410     TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) const  {   return IterateChildren (_value.c_str (), previous); }   ///< STL std::string form.
00411     #endif
00412 
00413     /** Add a new node related to this. Adds a child past the LastChild.
00414         Returns a pointer to the new object or NULL if an error occured.
00415     */
00416     TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
00417 
00418 
00419     /** Add a new node related to this. Adds a child past the LastChild.
00420 
00421         NOTE: the node to be added is passed by pointer, and will be
00422         henceforth owned (and deleted) by tinyXml. This method is efficient
00423         and avoids an extra copy, but should be used with care as it
00424         uses a different memory model than the other insert functions.
00425 
00426         @sa InsertEndChild
00427     */
00428     TiXmlNode* LinkEndChild( TiXmlNode* addThis );
00429     TiXmlNode* LinkAfterChild( TiXmlNode* afterThis, TiXmlNode* addThis );
00430 
00431     /** Add a new node related to this. Adds a child before the specified child.
00432         Returns a pointer to the new object or NULL if an error occured.
00433     */
00434     TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
00435 
00436     /** Add a new node related to this. Adds a child after the specified child.
00437         Returns a pointer to the new object or NULL if an error occured.
00438     */
00439     TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
00440 
00441     /** Replace a child of this node.
00442         Returns a pointer to the new object or NULL if an error occured.
00443     */
00444     TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
00445 
00446     /// Delete a child of this node.
00447     bool RemoveChild( TiXmlNode* removeThis );
00448 
00449     /// Navigate to a sibling node.
00450     TiXmlNode* PreviousSibling() const          { return prev; }
00451 
00452     /// Navigate to a sibling node.
00453     TiXmlNode* PreviousSibling( const char * ) const;
00454 
00455     #ifdef TIXML_USE_STL
00456     TiXmlNode* PreviousSibling( const std::string& _value ) const   {   return PreviousSibling (_value.c_str ());   }   ///< STL std::string form.
00457     TiXmlNode* NextSibling( const std::string& _value) const        {   return NextSibling (_value.c_str ());   }   ///< STL std::string form.
00458     #endif
00459 
00460     /// Navigate to a sibling node.
00461     TiXmlNode* NextSibling() const              { return next; }
00462 
00463     /// Navigate to a sibling node with the given 'value'.
00464     TiXmlNode* NextSibling( const char * ) const;
00465 
00466     /** Convenience function to get through elements.
00467         Calls NextSibling and ToElement. Will skip all non-Element
00468         nodes. Returns 0 if there is not another element.
00469     */
00470     TiXmlElement* NextSiblingElement() const;
00471 
00472     /** Convenience function to get through elements.
00473         Calls NextSibling and ToElement. Will skip all non-Element
00474         nodes. Returns 0 if there is not another element.
00475     */
00476     TiXmlElement* NextSiblingElement( const char * ) const;
00477 
00478     #ifdef TIXML_USE_STL
00479     TiXmlElement* NextSiblingElement( const std::string& _value) const  {   return NextSiblingElement (_value.c_str ());    }   ///< STL std::string form.
00480     #endif
00481 
00482     /// Convenience function to get through elements.
00483     TiXmlElement* FirstChildElement()   const;
00484 
00485     /// Convenience function to get through elements.
00486     TiXmlElement* FirstChildElement( const char * value ) const;
00487 
00488     #ifdef TIXML_USE_STL
00489     TiXmlElement* FirstChildElement( const std::string& _value ) const  {   return FirstChildElement (_value.c_str ()); }   ///< STL std::string form.
00490     #endif
00491 
00492     /** Query the type (as an enumerated value, above) of this node.
00493         The possible types are: DOCUMENT, ELEMENT, COMMENT,
00494                                 UNKNOWN, TEXT, and DECLARATION.
00495     */
00496     virtual int Type() const    { return type; }
00497 
00498     /** Return a pointer to the Document this node lives in.
00499         Returns null if not in a document.
00500     */
00501     TiXmlDocument* GetDocument() const;
00502 
00503     /// Returns true if this node has no children.
00504     bool NoChildren() const                     { return !firstChild; }
00505 
00506     TiXmlDocument* ToDocument() const       { return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00507     TiXmlElement*  ToElement() const        { return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00508     TiXmlComment*  ToComment() const        { return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00509     TiXmlUnknown*  ToUnknown() const        { return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00510     TiXmlText*     ToText()    const        { return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00511     TiXmlDeclaration* ToDeclaration() const { return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
00512 
00513     virtual TiXmlNode* Clone() const = 0;
00514 
00515     void  SetUserData( void* user )         { userData = user; }
00516     void* GetUserData()                     { return userData; }
00517 
00518 protected:
00519     TiXmlNode( NodeType type );
00520 
00521     #ifdef TIXML_USE_STL
00522         // The real work of the input operator.
00523         virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
00524     #endif
00525 
00526     // Figure out what is at *p, and parse it. Returns null if it is not an xml node.
00527     TiXmlNode* Identify( const char* start );
00528     void CopyToClone( TiXmlNode* target ) const { target->SetValue (value.c_str() );
00529                                                   target->userData = userData; }
00530 
00531     // Internal Value function returning a TIXML_STRING
00532     TIXML_STRING SValue() const { return value ; }
00533 
00534     TiXmlNode*      parent;
00535     NodeType        type;
00536 
00537     TiXmlNode*      firstChild;
00538     TiXmlNode*      lastChild;
00539 
00540     TIXML_STRING    value;
00541 
00542     TiXmlNode*      prev;
00543     TiXmlNode*      next;
00544     void*           userData;
00545 };
00546 
00547 
00548 /** An attribute is a name-value pair. Elements have an arbitrary
00549     number of attributes, each with a unique name.
00550 
00551     @note The attributes are not TiXmlNodes, since they are not
00552           part of the tinyXML document object model. There are other
00553           suggested ways to look at this problem.
00554 */
00555 class TiXmlAttribute : public TiXmlBase
00556 {
00557     friend class TiXmlAttributeSet;
00558 
00559 public:
00560     /// Construct an empty attribute.
00561     TiXmlAttribute()
00562     {
00563         document = 0;
00564         prev = next = 0;
00565     }
00566 
00567     #ifdef TIXML_USE_STL
00568     /// std::string constructor.
00569     TiXmlAttribute( const std::string& _name, const std::string& _value )
00570     {
00571         name = _name;
00572         value = _value;
00573         document = 0;
00574         prev = next = 0;
00575     }
00576     #endif
00577 
00578     /// Construct an attribute with a name and value.
00579     TiXmlAttribute( const char * _name, const char * _value )
00580     {
00581         name = _name;
00582         value = _value;
00583         document = 0;
00584         prev = next = 0;
00585     }
00586 
00587     const char*     Name()  const       { return name.c_str (); }       ///< Return the name of this attribute.
00588     const char*     Value() const       { return value.c_str (); }      ///< Return the value of this attribute.
00589     const int       IntValue() const;                                   ///< Return the value of this attribute, converted to an integer.
00590     const double    DoubleValue() const;                                ///< Return the value of this attribute, converted to a double.
00591 
00592     /** QueryIntValue examines the value string. It is an alternative to the
00593         IntValue() method with richer error checking.
00594         If the value is an integer, it is stored in 'value' and 
00595         the call returns TIXML_SUCCESS. If it is not
00596         an integer, it returns TIXML_WRONG_TYPE.
00597 
00598         A specialized but useful call. Note that for success it returns 0,
00599         which is the opposite of almost all other TinyXml calls.
00600     */
00601     int QueryIntValue( int* value ) const;
00602     /// QueryDoubleValue examines the value string. See QueryIntValue().
00603     int QueryDoubleValue( double* value ) const;
00604 
00605     void SetName( const char* _name )   { name = _name; }               ///< Set the name of this attribute.
00606     void SetValue( const char* _value ) { value = _value; }             ///< Set the value.
00607 
00608     void SetIntValue( int value );                                      ///< Set the value from an integer.
00609     void SetDoubleValue( double value );                                ///< Set the value from a double.
00610 
00611     #ifdef TIXML_USE_STL
00612     /// STL std::string form.
00613     void SetName( const std::string& _name )    
00614     {   
00615         StringToBuffer buf( _name );
00616         SetName ( buf.buffer ? buf.buffer : "error" );  
00617     }
00618     /// STL std::string form.   
00619     void SetValue( const std::string& _value )  
00620     {   
00621         StringToBuffer buf( _value );
00622         SetValue( buf.buffer ? buf.buffer : "error" );  
00623     }
00624     #endif
00625 
00626     /// Get the next sibling attribute in the DOM. Returns null at end.
00627     TiXmlAttribute* Next() const;
00628     /// Get the previous sibling attribute in the DOM. Returns null at beginning.
00629     TiXmlAttribute* Previous() const;
00630 
00631     bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
00632     bool operator<( const TiXmlAttribute& rhs )  const { return name < rhs.name; }
00633     bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
00634 
00635     /*  [internal use]
00636         Attribtue parsing starts: first letter of the name
00637                          returns: the next char after the value end quote
00638     */
00639     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00640 
00641     // [internal use]
00642     virtual void Print( FILE* cfile, int depth ) const;
00643 
00644     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00645     // [internal use]
00646     // Set the document pointer so the attribute can report errors.
00647     void SetDocument( TiXmlDocument* doc )  { document = doc; }
00648 
00649 private:
00650     TiXmlDocument*  document;   // A pointer back to a document, for error reporting.
00651     TIXML_STRING name;
00652     TIXML_STRING value;
00653     TiXmlAttribute* prev;
00654     TiXmlAttribute* next;
00655 };
00656 
00657 
00658 /*  A class used to manage a group of attributes.
00659     It is only used internally, both by the ELEMENT and the DECLARATION.
00660     
00661     The set can be changed transparent to the Element and Declaration
00662     classes that use it, but NOT transparent to the Attribute
00663     which has to implement a next() and previous() method. Which makes
00664     it a bit problematic and prevents the use of STL.
00665 
00666     This version is implemented with circular lists because:
00667         - I like circular lists
00668         - it demonstrates some independence from the (typical) doubly linked list.
00669 */
00670 class TiXmlAttributeSet
00671 {
00672 public:
00673     TiXmlAttributeSet();
00674     ~TiXmlAttributeSet();
00675 
00676     void Add( TiXmlAttribute* attribute );
00677     void Remove( TiXmlAttribute* attribute );
00678 
00679     TiXmlAttribute* First() const   { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
00680     TiXmlAttribute* Last()  const   { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
00681     TiXmlAttribute* Find( const char * name ) const;
00682 
00683 private:
00684     TiXmlAttribute sentinel;
00685 };
00686 
00687 
00688 /** The element is a container class. It has a value, the element name,
00689     and can contain other elements, text, comments, and unknowns.
00690     Elements also contain an arbitrary number of attributes.
00691 */
00692 class TiXmlElement : public TiXmlNode
00693 {
00694 public:
00695     /// Construct an element.
00696     TiXmlElement (const char * in_value);
00697 
00698     #ifdef TIXML_USE_STL
00699     /// std::string constructor.
00700     TiXmlElement( const std::string& _value ) :     TiXmlNode( TiXmlNode::ELEMENT )
00701     {
00702         firstChild = lastChild = 0;
00703         value = _value;
00704     }
00705     #endif
00706 
00707     virtual ~TiXmlElement();
00708 
00709     /** Given an attribute name, Attribute() returns the value
00710         for the attribute of that name, or null if none exists.
00711     */
00712     const char* Attribute( const char* name ) const;
00713 
00714     /** Given an attribute name, Attribute() returns the value
00715         for the attribute of that name, or null if none exists.
00716         If the attribute exists and can be converted to an integer,
00717         the integer value will be put in the return 'i', if 'i'
00718         is non-null.
00719     */
00720     const char* Attribute( const char* name, int* i ) const;
00721 
00722     /** Given an attribute name, Attribute() returns the value
00723         for the attribute of that name, or null if none exists.
00724         If the attribute exists and can be converted to an double,
00725         the double value will be put in the return 'd', if 'd'
00726         is non-null.
00727     */
00728     const char* Attribute( const char* name, double* d ) const;
00729 
00730     /** QueryIntAttribute examines the attribute - it is an alternative to the
00731         Attribute() method with richer error checking.
00732         If the attribute is an integer, it is stored in 'value' and 
00733         the call returns TIXML_SUCCESS. If it is not
00734         an integer, it returns TIXML_WRONG_TYPE. If the attribute
00735         does not exist, then TIXML_NO_ATTRIBUTE is returned.
00736     */  
00737     int QueryIntAttribute( const char* name, int* value ) const;
00738     /// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
00739     int QueryDoubleAttribute( const char* name, double* value ) const;
00740 
00741     /** Sets an attribute of name to a given value. The attribute
00742         will be created if it does not exist, or changed if it does.
00743     */
00744     void SetAttribute( const char* name, const char * value );
00745 
00746     #ifdef TIXML_USE_STL
00747     const char* Attribute( const std::string& name ) const              { return Attribute( name.c_str() ); }
00748     const char* Attribute( const std::string& name, int* i ) const      { return Attribute( name.c_str(), i ); }
00749 
00750     /// STL std::string form.
00751     void SetAttribute( const std::string& name, const std::string& _value ) 
00752     {   
00753         StringToBuffer n( name );
00754         StringToBuffer v( _value );
00755         if ( n.buffer && v.buffer )
00756             SetAttribute (n.buffer, v.buffer ); 
00757     }   
00758     ///< STL std::string form.
00759     void SetAttribute( const std::string& name, int _value )    
00760     {   
00761         StringToBuffer n( name );
00762         if ( n.buffer )
00763             SetAttribute (n.buffer, _value);    
00764     }   
00765     #endif
00766 
00767     /** Sets an attribute of name to a given value. The attribute
00768         will be created if it does not exist, or changed if it does.
00769     */
00770     void SetAttribute( const char * name, int value );
00771 
00772     /** Deletes an attribute with the given name.
00773     */
00774     void RemoveAttribute( const char * name );
00775     #ifdef TIXML_USE_STL
00776     void RemoveAttribute( const std::string& name ) {   RemoveAttribute (name.c_str ());    }   ///< STL std::string form.
00777     #endif
00778 
00779     TiXmlAttribute* FirstAttribute() const  { return attributeSet.First(); }        ///< Access the first attribute in this element.
00780     TiXmlAttribute* LastAttribute() const   { return attributeSet.Last(); }     ///< Access the last attribute in this element.
00781 
00782     // [internal use] Creates a new Element and returs it.
00783     virtual TiXmlNode* Clone() const;
00784     // [internal use]
00785 
00786     virtual void Print( FILE* cfile, int depth ) const;
00787 
00788 protected:
00789 
00790     // Used to be public [internal use]
00791     #ifdef TIXML_USE_STL
00792         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00793     #endif
00794     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00795 
00796     /*  [internal use]
00797         Attribtue parsing starts: next char past '<'
00798                          returns: next char past '>'
00799     */
00800     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00801 
00802     /*  [internal use]
00803         Reads the "value" of the element -- another element, or text.
00804         This should terminate with the current end tag.
00805     */
00806     const char* ReadValue( const char* in, TiXmlParsingData* prevData );
00807 
00808 private:
00809     TiXmlAttributeSet attributeSet;
00810 };
00811 
00812 
00813 /** An XML comment.
00814 */
00815 class TiXmlComment : public TiXmlNode
00816 {
00817 public:
00818     /// Constructs an empty comment.
00819     TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
00820     virtual ~TiXmlComment() {}
00821 
00822     // [internal use] Creates a new Element and returs it.
00823     virtual TiXmlNode* Clone() const;
00824     // [internal use]
00825     virtual void Print( FILE* cfile, int depth ) const;
00826 protected:
00827     // used to be public
00828     #ifdef TIXML_USE_STL
00829         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00830     #endif
00831     virtual void StreamOut( TIXML_OSTREAM * out ) const;
00832     /*  [internal use]
00833         Attribtue parsing starts: at the ! of the !--
00834                          returns: next char past '>'
00835     */
00836     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00837 };
00838 
00839 
00840 /** XML text. Contained in an element.
00841 */
00842 class TiXmlText : public TiXmlNode
00843 {
00844     friend class TiXmlElement;
00845 public:
00846     /// Constructor.
00847     TiXmlText (const char * initValue) : TiXmlNode (TiXmlNode::TEXT)
00848     {
00849         SetValue( initValue );
00850     }
00851     virtual ~TiXmlText() {}
00852 
00853     #ifdef TIXML_USE_STL
00854     /// Constructor.
00855     TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
00856     {
00857         SetValue( initValue );
00858     }
00859     #endif
00860 
00861     // [internal use]
00862     virtual void Print( FILE* cfile, int depth ) const;
00863 
00864 protected :
00865     // [internal use] Creates a new Element and returns it.
00866     virtual TiXmlNode* Clone() const;
00867     virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00868     // [internal use]
00869     bool Blank() const; // returns true if all white space and new lines
00870     /*  [internal use]
00871             Attribtue parsing starts: First char of the text
00872                              returns: next char past '>'
00873     */
00874     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00875     // [internal use]
00876     #ifdef TIXML_USE_STL
00877         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00878     #endif
00879 };
00880 
00881 
00882 /** In correct XML the declaration is the first entry in the file.
00883     @verbatim
00884         <?xml version="1.0" standalone="yes"?>
00885     @endverbatim
00886 
00887     TinyXml will happily read or write files without a declaration,
00888     however. There are 3 possible attributes to the declaration:
00889     version, encoding, and standalone.
00890 
00891     Note: In this version of the code, the attributes are
00892     handled as special cases, not generic attributes, simply
00893     because there can only be at most 3 and they are always the same.
00894 */
00895 class TiXmlDeclaration : public TiXmlNode
00896 {
00897 public:
00898     /// Construct an empty declaration.
00899     TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
00900 
00901 #ifdef TIXML_USE_STL
00902     /// Constructor.
00903     TiXmlDeclaration(   const std::string& _version,
00904                         const std::string& _encoding,
00905                         const std::string& _standalone )
00906             : TiXmlNode( TiXmlNode::DECLARATION )
00907     {
00908         version = _version;
00909         encoding = _encoding;
00910         standalone = _standalone;
00911     }
00912 #endif
00913 
00914     /// Construct.
00915     TiXmlDeclaration(   const char* _version,
00916                         const char* _encoding,
00917                         const char* _standalone );
00918 
00919     virtual ~TiXmlDeclaration() {}
00920 
00921     /// Version. Will return empty if none was found.
00922     const char * Version() const        { return version.c_str (); }
00923     /// Encoding. Will return empty if none was found.
00924     const char * Encoding() const       { return encoding.c_str (); }
00925     /// Is this a standalone document?
00926     const char * Standalone() const     { return standalone.c_str (); }
00927 
00928     // [internal use] Creates a new Element and returs it.
00929     virtual TiXmlNode* Clone() const;
00930     // [internal use]
00931     virtual void Print( FILE* cfile, int depth ) const;
00932 
00933 protected:
00934     // used to be public
00935     #ifdef TIXML_USE_STL
00936         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00937     #endif
00938     virtual void StreamOut ( TIXML_OSTREAM * out) const;
00939     //  [internal use]
00940     //  Attribtue parsing starts: next char past '<'
00941     //                   returns: next char past '>'
00942 
00943     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00944 
00945 private:
00946     TIXML_STRING version;
00947     TIXML_STRING encoding;
00948     TIXML_STRING standalone;
00949 };
00950 
00951 
00952 /** Any tag that tinyXml doesn't recognize is saved as an
00953     unknown. It is a tag of text, but should not be modified.
00954     It will be written back to the XML, unchanged, when the file
00955     is saved.
00956 */
00957 class TiXmlUnknown : public TiXmlNode
00958 {
00959 public:
00960     TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN ) {}
00961     virtual ~TiXmlUnknown() {}
00962 
00963     // [internal use]
00964     virtual TiXmlNode* Clone() const;
00965     // [internal use]
00966     virtual void Print( FILE* cfile, int depth ) const;
00967 protected:
00968     #ifdef TIXML_USE_STL
00969         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
00970     #endif
00971     virtual void StreamOut ( TIXML_OSTREAM * out ) const;
00972     /*  [internal use]
00973         Attribute parsing starts: First char of the text
00974                          returns: next char past '>'
00975     */
00976     virtual const char* Parse( const char* p, TiXmlParsingData* data );
00977 };
00978 
00979 
00980 /** Always the top level node. A document binds together all the
00981     XML pieces. It can be saved, loaded, and printed to the screen.
00982     The 'value' of a document node is the xml file name.
00983 */
00984 class TiXmlDocument : public TiXmlNode
00985 {
00986 public:
00987     /// Create an empty document, that has no name.
00988     TiXmlDocument();
00989     /// Create a document with a name. The name of the document is also the filename of the xml.
00990     TiXmlDocument( const char * documentName );
00991 
00992     #ifdef TIXML_USE_STL
00993     /// Constructor.
00994     TiXmlDocument( const std::string& documentName ) :
00995         TiXmlNode( TiXmlNode::DOCUMENT )
00996     {
00997         value = documentName;
00998         error = false;
00999     }
01000     #endif
01001 
01002     virtual ~TiXmlDocument() {}
01003 
01004     /** Load a file using the current document value.
01005         Returns true if successful. Will delete any existing
01006         document data before loading.
01007     */
01008     bool LoadFile();
01009     /// Save a file using the current document value. Returns true if successful.
01010     bool SaveFile() const;
01011     /// Load a file using the given filename. Returns true if successful.
01012     bool LoadFile( const char * filename );
01013     /// Save a file using the given filename. Returns true if successful.
01014     bool SaveFile( const char * filename ) const;
01015 
01016     #ifdef TIXML_USE_STL
01017     bool LoadFile( const std::string& filename )            ///< STL std::string version.
01018     {
01019         StringToBuffer f( filename );
01020         return ( f.buffer && LoadFile( f.buffer ));
01021     }
01022     bool SaveFile( const std::string& filename ) const      ///< STL std::string version.
01023     {
01024         StringToBuffer f( filename );
01025         return ( f.buffer && SaveFile( f.buffer ));
01026     }
01027     #endif
01028 
01029     /** Parse the given null terminated block of xml data.
01030     */
01031     virtual const char* Parse( const char* p, TiXmlParsingData* data = 0 );
01032 
01033     /** Get the root element -- the only top level element -- of the document.
01034         In well formed XML, there should only be one. TinyXml is tolerant of
01035         multiple elements at the document level.
01036     */
01037     TiXmlElement* RootElement() const       { return FirstChildElement(); }
01038 
01039     /** If an error occurs, Error will be set to true. Also,
01040         - The ErrorId() will contain the integer identifier of the error (not generally useful)
01041         - The ErrorDesc() method will return the name of the error. (very useful)
01042         - The ErrorRow() and ErrorCol() will return the location of the error (if known)
01043     */  
01044     bool Error() const                      { return error; }
01045 
01046     /// Contains a textual (english) description of the error if one occurs.
01047     const char * ErrorDesc() const  { return errorDesc.c_str (); }
01048 
01049     /** Generally, you probably want the error string ( ErrorDesc() ). But if you
01050         prefer the ErrorId, this function will fetch it.
01051     */
01052     const int ErrorId() const               { return errorId; }
01053 
01054     /** Returns the location (if known) of the error. The first column is column 1, 
01055         and the first row is row 1. A value of 0 means the row and column wasn't applicable
01056         (memory errors, for example, have no row/column) or the parser lost the error. (An
01057         error in the error reporting, in that case.)
01058 
01059         @sa SetTabSize, Row, Column
01060     */
01061     int ErrorRow()  { return errorLocation.row+1; }
01062     int ErrorCol()  { return errorLocation.col+1; } ///< The column where the error occured. See ErrorRow()
01063 
01064     /** By calling this method, with a tab size
01065         greater than 0, the row and column of each node and attribute is stored
01066         when the file is loaded. Very useful for tracking the DOM back in to
01067         the source file.
01068 
01069         The tab size is required for calculating the location of nodes. If not
01070         set, the default of 4 is used. The tabsize is set per document. Setting
01071         the tabsize to 0 disables row/column tracking.
01072 
01073         Note that row and column tracking is not supported when using operator>>.
01074 
01075         The tab size needs to be enabled before the parse or load. Correct usage:
01076         @verbatim
01077         TiXmlDocument doc;
01078         doc.SetTabSize( 8 );
01079         doc.Load( "myfile.xml" );
01080         @endverbatim
01081 
01082         @sa Row, Column
01083     */
01084     void SetTabSize( int _tabsize )     { tabsize = _tabsize; }
01085 
01086     int TabSize() const { return tabsize; }
01087 
01088     /** If you have handled the error, it can be reset with this call. The error
01089         state is automatically cleared if you Parse a new XML block.
01090     */
01091     void ClearError()                       {   error = false; 
01092                                                 errorId = 0; 
01093                                                 errorDesc = ""; 
01094                                                 errorLocation.row = errorLocation.col = 0; 
01095                                                 //errorLocation.last = 0; 
01096                                             }
01097 
01098     /** Dump the document to standard out. */
01099     void Print() const                      { Print( stdout, 0 ); }
01100 
01101     // [internal use]
01102     virtual void Print( FILE* cfile, int depth = 0 ) const;
01103     // [internal use]
01104     void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData );
01105 
01106 protected :
01107     virtual void StreamOut ( TIXML_OSTREAM * out) const;
01108     // [internal use]
01109     virtual TiXmlNode* Clone() const;
01110     #ifdef TIXML_USE_STL
01111         virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
01112     #endif
01113 
01114 private:
01115     bool error;
01116     int  errorId;
01117     TIXML_STRING errorDesc;
01118     int tabsize;
01119     TiXmlCursor errorLocation;
01120 };
01121 
01122 
01123 /**
01124     A TiXmlHandle is a class that wraps a node pointer with null checks; this is
01125     an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
01126     DOM structure. It is a separate utility class.
01127 
01128     Take an example:
01129     @verbatim
01130     <Document>
01131         <Element attributeA = "valueA">
01132             <Child attributeB = "value1" />
01133             <Child attributeB = "value2" />
01134         </Element>
01135     <Document>
01136     @endverbatim
01137 
01138     Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
01139     easy to write a *lot* of code that looks like:
01140 
01141     @verbatim
01142     TiXmlElement* root = document.FirstChildElement( "Document" );
01143     if ( root )
01144     {
01145         TiXmlElement* element = root->FirstChildElement( "Element" );
01146         if ( element )
01147         {
01148             TiXmlElement* child = element->FirstChildElement( "Child" );
01149             if ( child )
01150             {
01151                 TiXmlElement* child2 = child->NextSiblingElement( "Child" );
01152                 if ( child2 )
01153                 {
01154                     // Finally do something useful.
01155     @endverbatim
01156 
01157     And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
01158     of such code. A TiXmlHandle checks for null pointers so it is perfectly safe 
01159     and correct to use:
01160 
01161     @verbatim
01162     TiXmlHandle docHandle( &document );
01163     TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
01164     if ( child2 )
01165     {
01166         // do something useful
01167     @endverbatim
01168 
01169     Which is MUCH more concise and useful.
01170 
01171     It is also safe to copy handles - internally they are nothing more than node pointers.
01172     @verbatim
01173     TiXmlHandle handleCopy = handle;
01174     @endverbatim
01175 
01176     What they should not be used for is iteration:
01177 
01178     @verbatim
01179     int i=0; 
01180     while ( true )
01181     {
01182         TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
01183         if ( !child )
01184             break;
01185         // do something
01186         ++i;
01187     }
01188     @endverbatim
01189 
01190     It seems reasonable, but it is in fact two embedded while loops. The Child method is 
01191     a linear walk to find the element, so this code would iterate much more than it needs 
01192     to. Instead, prefer:
01193 
01194     @verbatim
01195     TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
01196 
01197     for( child; child; child=child->NextSiblingElement() )
01198     {
01199         // do something
01200     }
01201     @endverbatim
01202 */
01203 class TiXmlHandle
01204 {
01205 public:
01206     /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
01207     TiXmlHandle( TiXmlNode* node )          { this->node = node; }
01208     /// Copy constructor
01209     TiXmlHandle( const TiXmlHandle& ref )   { this->node = ref.node; }
01210 
01211     /// Return a handle to the first child node.
01212     TiXmlHandle FirstChild() const;
01213     /// Return a handle to the first child node with the given name.
01214     TiXmlHandle FirstChild( const char * value ) const;
01215     /// Return a handle to the first child element.
01216     TiXmlHandle FirstChildElement() const;
01217     /// Return a handle to the first child element with the given name.
01218     TiXmlHandle FirstChildElement( const char * value ) const;
01219 
01220     /** Return a handle to the "index" child with the given name. 
01221         The first child is 0, the second 1, etc.
01222     */
01223     TiXmlHandle Child( const char* value, int index ) const;
01224     /** Return a handle to the "index" child. 
01225         The first child is 0, the second 1, etc.
01226     */
01227     TiXmlHandle Child( int index ) const;
01228     /** Return a handle to the "index" child element with the given name. 
01229         The first child element is 0, the second 1, etc. Note that only TiXmlElements
01230         are indexed: other types are not counted.
01231     */
01232     TiXmlHandle ChildElement( const char* value, int index ) const;
01233     /** Return a handle to the "index" child element. 
01234         The first child element is 0, the second 1, etc. Note that only TiXmlElements
01235         are indexed: other types are not counted.
01236     */
01237     TiXmlHandle ChildElement( int index ) const;
01238 
01239     #ifdef TIXML_USE_STL
01240     TiXmlHandle FirstChild( const std::string& _value ) const           { return FirstChild( _value.c_str() ); }
01241     TiXmlHandle FirstChildElement( const std::string& _value ) const        { return FirstChildElement( _value.c_str() ); }
01242 
01243     TiXmlHandle Child( const std::string& _value, int index ) const         { return Child( _value.c_str(), index ); }
01244     TiXmlHandle ChildElement( const std::string& _value, int index ) const  { return ChildElement( _value.c_str(), index ); }
01245     #endif
01246 
01247     /// Return the handle as a TiXmlNode. This may return null.
01248     TiXmlNode* Node() const         { return node; } 
01249     /// Return the handle as a TiXmlElement. This may return null.
01250     TiXmlElement* Element() const   { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
01251     /// Return the handle as a TiXmlText. This may return null.
01252     TiXmlText* Text() const         { return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
01253 
01254 private:
01255     TiXmlNode* node;
01256 };
01257 
01258 
01259 #endif
01260 

Generated on Mon Sep 12 19:58:57 2005 for Destiny3D by doxygen1.3-rc3